ASP NET - Tornando a Master Page Relativa

Caracterizando o problema

Todos sabemos que um aplicativo ASP NET abriga elementos 'NÃO ASP NET' e isso algumas vezes causa alguns problemas porque quando o ASP NET trabalha o item ele, por exemplo, sabe qual a página root do site ( símbolo ~ ) mas se na nossa home page eu utilizo, por exemplo, uma imagem na pasta imagens ? Note que o parâmetro src da imagem não é tratada pelo asp net e por esse motivo é um endereço estático, só funciona numa determinada situação.

Explicando melhor, se a pagina mestre estiver no root do site e a minha página que usa a página mestre também estiver no root do site não há problemas, ambas 'enxergam' a pasta imagens porque estão no 'mesmo nível', no root do site.

Neste caso as imagens da página mestre serão exibidas sem problema.

Quando a página não está no mesmo nível da página mestre

Supondo que eu seja um cara organizado e crie pastas para abrigarem páginas 'afins' ou por finalidade, por exemplo, a página FrmMudarSenha.aspx vai ficar na pasta usuario que é onde estão todas as páginas que trabalham com usuário estão.

Se a página FrmMudarSenha.aspx ( que agora está na pasta usuario ) usar na diretiva '@Page' a página mestre MasterPageFile="~/SiteMaster.master" teremos um problema...todas as imagens usadas na master page não serão exibidas porque a master page é tratada pelo ASP NET e entende o root do site ( ~ ) mas as imagens dentro da Home Page são estáticas e ao encontrar o parâmetro src da imagem como 'imagens/flor.png' elas NÃO farão isso em relação ao root do site mas sim na localização da página atual, ou seja, em 'usuario/imagens/flor.png' e como essa pasta não existe as imagens não serão exibidas.

Soluções para o problema

O segredo é fazer com que o ASP NET trate a imagem colocando o endereço relativo em relação ao root do site e não a página corrente.


• 1 - A maneira mais simples e idiota de corrigir este problema é copiar a pasta imagens do root para todas as sub-pastas do site.

Se são poucas sub-pastas, poucas imagens não é uma má solução.


• 2 - Fazer o asp net montar a url da imagem:
<img src="<%=ResolveUrl("~/imagens/flor.png") %>" alt="flor" id="flor" />

Eu sou programador desde a época do ASP Clássico e tenho traumas de colocar response.write numa página ASPx...Não gosto da solução mas funciona bem.


• 3 - Carregar a imagem pelo próprio ASP NET.
<asp:Image runat="server" src="~/imagens/flor.png" ></asp:Image>

Não gosto desta solução porque acho ruim ter um monte de objetos 'runat=server' para tratar...acaba gerando confusão de nomes, para achar um item no meio de tantos começa a ficar moroso, entre outras coisas.


• 4 - Deixar o ASP NET tratar a imagem.
<img src="~/imagens/flor.png" alt="flor" runat="server" ID="flor" />

Melhor que a solução 1 e bem mais elegante que a solução 2. Quanto a solução 3 a acho esta solução melhor porque a tag img é nativa do HTML e não do ASP NET e, ao meu ver, é menos 'poluente' que a solução 3 porque num postback o servidor não precisaria tratar esse elemento e seria usada a imagem em cache anterior do browser. Prefiro esta solução.